OpenSSL中文手册之ERR库详解

您所在的位置:网站首页 unknown nca magic翻译 OpenSSL中文手册之ERR库详解

OpenSSL中文手册之ERR库详解

2024-01-17 12:50| 来源: 网络整理| 查看: 265

  版权声明:本文根据DragonKing牛,E-Mail:[email protected]发布在https://openssl.126.com的系列文章整理修改而成(这个网站已经不能访问了),我自己所做的工作主要是针对新的1.0.2版本进行验证,修改错别字,和错误,重新排版,以及整理分类,配图。 未经作者允许,严禁用于商业出版,否则追究法律责任。网络转载请注明出处,这是对原创者的起码的尊重!!!

1 概述

  程序设计时,一般通过函数的返回值来判断是否调用成功。设计良好的函数以及好的错误处理能帮助调用者快速找到错误原因。错误处理应该尽可能多的包含各种信息,包括:

错误码;出错文件以及行号;错误原因;出错函数;出错库;出错模块与类别信息;错误堆栈信息等。出错信息最好能支持多种输出。可以是输出在标准输出上,也可以是文件等形式。 2 相关数据结构 2.1 错误代码

  openssl中,通过unsigned long类型来存放错误信息。它包含三部分内容:库代码、函数代码以及错误原因代码。其中,库代码在openssl/err.h中定义,比如err.h中为库定义如下库代码:

/* library */ # define ERR_LIB_NONE 1 # define ERR_LIB_SYS 2 # define ERR_LIB_BN 3 # define ERR_LIB_RSA 4 # define ERR_LIB_DH 5 # define ERR_LIB_EVP 6 # define ERR_LIB_BUF 7 # define ERR_LIB_OBJ 8 # define ERR_LIB_PEM 9 # define ERR_LIB_DSA 10 # define ERR_LIB_X509 11 /* #define ERR_LIB_METH 12 */ # define ERR_LIB_ASN1 13 # define ERR_LIB_CONF 14 # define ERR_LIB_CRYPTO 15 # define ERR_LIB_EC 16 # define ERR_LIB_SSL 20 /* #define ERR_LIB_SSL23 21 */ /* #define ERR_LIB_SSL2 22 */ /* #define ERR_LIB_SSL3 23 */ /* #define ERR_LIB_RSAREF 30 */ /* #define ERR_LIB_PROXY 31 */ # define ERR_LIB_BIO 32 # define ERR_LIB_PKCS7 33 # define ERR_LIB_X509V3 34 # define ERR_LIB_PKCS12 35 # define ERR_LIB_RAND 36 # define ERR_LIB_DSO 37 # define ERR_LIB_ENGINE 38 # define ERR_LIB_OCSP 39 # define ERR_LIB_UI 40 # define ERR_LIB_COMP 41 # define ERR_LIB_ECDSA 42 # define ERR_LIB_ECDH 43 # define ERR_LIB_STORE 44 # define ERR_LIB_FIPS 45 # define ERR_LIB_CMS 46 # define ERR_LIB_TS 47 # define ERR_LIB_HMAC 48 /* # define ERR_LIB_JPAKE 49 */ # define ERR_LIB_CT 50 # define ERR_LIB_ASYNC 51 # define ERR_LIB_KDF 52 # define ERR_LIB_USER 128

  函数代码以及错误原因代码由各个功能模块定义(同类代码不能与其他的重复,也不能超过一定的大小)。如:openssl/bio.h中定义了如下函数和错误原因代号:

/* Error codes for the BIO functions. */ /* Function codes. */ # define BIO_F_ACPT_STATE 100 # define BIO_F_ADDR_STRINGS 134 # define BIO_F_BIO_ACCEPT 101 # define BIO_F_BIO_ACCEPT_EX 137 # define BIO_F_BIO_ADDR_NEW 144 # define BIO_F_BIO_CALLBACK_CTRL 131 # define BIO_F_BIO_CONNECT 138 # define BIO_F_BIO_CTRL 103 # define BIO_F_BIO_GETS 104 # define BIO_F_BIO_GET_HOST_IP 106 # define BIO_F_BIO_GET_NEW_INDEX 102 # define BIO_F_BIO_GET_PORT 107 # define BIO_F_BIO_LISTEN 139 # define BIO_F_BIO_LOOKUP 135 # define BIO_F_BIO_MAKE_PAIR 121 # define BIO_F_BIO_NEW 108 # define BIO_F_BIO_NEW_FILE 109 # define BIO_F_BIO_NEW_MEM_BUF 126 # define BIO_F_BIO_NREAD 123 # define BIO_F_BIO_NREAD0 124 # define BIO_F_BIO_NWRITE 125 # define BIO_F_BIO_NWRITE0 122 # define BIO_F_BIO_PARSE_HOSTSERV 136 # define BIO_F_BIO_PUTS 110 # define BIO_F_BIO_READ 111 # define BIO_F_BIO_SOCKET 140 # define BIO_F_BIO_SOCKET_NBIO 142 # define BIO_F_BIO_SOCK_INFO 141 # define BIO_F_BIO_SOCK_INIT 112 # define BIO_F_BIO_WRITE 113 # define BIO_F_BUFFER_CTRL 114 # define BIO_F_CONN_CTRL 127 # define BIO_F_CONN_STATE 115 # define BIO_F_DGRAM_SCTP_READ 132 # define BIO_F_DGRAM_SCTP_WRITE 133 # define BIO_F_FILE_CTRL 116 # define BIO_F_FILE_READ 130 # define BIO_F_LINEBUFFER_CTRL 129 # define BIO_F_MEM_WRITE 117 # define BIO_F_SSL_NEW 118 /* Reason codes. */ # define BIO_R_ACCEPT_ERROR 100 # define BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET 141 # define BIO_R_AMBIGUOUS_HOST_OR_SERVICE 129 # define BIO_R_BAD_FOPEN_MODE 101 # define BIO_R_BROKEN_PIPE 124 # define BIO_R_CONNECT_ERROR 103 # define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 # define BIO_R_GETSOCKNAME_ERROR 132 # define BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS 133 # define BIO_R_GETTING_SOCKTYPE 134 # define BIO_R_INVALID_ARGUMENT 125 # define BIO_R_INVALID_SOCKET 135 # define BIO_R_IN_USE 123 # define BIO_R_LISTEN_V6_ONLY 136 # define BIO_R_LOOKUP_RETURNED_NOTHING 142 # define BIO_R_MALFORMED_HOST_OR_SERVICE 130 # define BIO_R_NBIO_CONNECT_ERROR 110 # define BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED 143 # define BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED 144 # define BIO_R_NO_PORT_DEFINED 113 # define BIO_R_NO_SUCH_FILE 128 # define BIO_R_NULL_PARAMETER 115 # define BIO_R_UNABLE_TO_BIND_SOCKET 117 # define BIO_R_UNABLE_TO_CREATE_SOCKET 118 # define BIO_R_UNABLE_TO_KEEPALIVE 137 # define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 # define BIO_R_UNABLE_TO_NODELAY 138 # define BIO_R_UNABLE_TO_REUSEADDR 139 # define BIO_R_UNAVAILABLE_IP_FAMILY 145 # define BIO_R_UNINITIALIZED 120 # define BIO_R_UNKNOWN_INFO_TYPE 140 # define BIO_R_UNSUPPORTED_IP_FAMILY 146 # define BIO_R_UNSUPPORTED_METHOD 121 # define BIO_R_UNSUPPORTED_PROTOCOL_FAMILY 131 # define BIO_R_WRITE_TO_READ_ONLY_BIO 126 # define BIO_R_WSASTARTUP 122

  错误代码通过上述三部分通过计算得到,并且根据此信息能提取各个代码。计算函数在err.h中定义如下:

/*由库代码,函数代码,原因代码计算错误代码*/ # define ERR_PACK(l,f,r) ( (((unsigned int)(l) & 0x0FF) 24L) & 0x0FFL) # define ERR_GET_FUNC(l) (int)(((l) >> 12L) & 0xFFFL) # define ERR_GET_REASON(l) (int)( (l) & 0xFFFL) # define ERR_FATAL_ERROR(l) (int)( (l) & ERR_R_FATAL) //致命错误

  可以看出,库的个数不能大于255(0xff),函数个数和错误原因不能大于4095(0xfff)。

2.2 基本数据结构

  主要数据结构有两个,定义在err.h中。

2.2.1 ERR_STRING_DATA typedef struct ERR_string_data_st { unsigned long error; //错误码 const char *string; //string用来存放文本信息,可以是函数名也可以是错误原因。 } ERR_STRING_DATA;

  该数据结构的内容由各个功能模块来设置。其中,error用来存放错误信息(由库代码、函数代码以及错误原因代码计算得来),string用来存放文本信息,可以是函数名也可以是错误原因。以crypto/bio/bio_err.c为例,它定义了两个全局表,分别用来存放函数信息和错误信息:

# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0) # define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason) static ERR_STRING_DATA BIO_str_functs[] = { {ERR_FUNC(BIO_F_ACPT_STATE), "acpt_state"}, {ERR_FUNC(BIO_F_ADDR_STRINGS), "addr_strings"}, {ERR_FUNC(BIO_F_BIO_ACCEPT), "BIO_accept"}, {ERR_FUNC(BIO_F_BIO_ACCEPT_EX), "BIO_accept_ex"}, {ERR_FUNC(BIO_F_BIO_ADDR_NEW), "BIO_ADDR_new"}, {ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL), "BIO_callback_ctrl"}, {ERR_FUNC(BIO_F_BIO_CONNECT), "BIO_connect"}, {ERR_FUNC(BIO_F_BIO_CTRL), "BIO_ctrl"}, {ERR_FUNC(BIO_F_BIO_GETS), "BIO_gets"}, {ERR_FUNC(BIO_F_BIO_GET_HOST_IP), "BIO_get_host_ip"}, {ERR_FUNC(BIO_F_BIO_GET_NEW_INDEX), "BIO_get_new_index"}, {ERR_FUNC(BIO_F_BIO_GET_PORT), "BIO_get_port"}, {ERR_FUNC(BIO_F_BIO_LISTEN), "BIO_listen"}, {ERR_FUNC(BIO_F_BIO_LOOKUP), "BIO_lookup"}, {ERR_FUNC(BIO_F_BIO_MAKE_PAIR), "bio_make_pair"}, {ERR_FUNC(BIO_F_BIO_NEW), "BIO_new"}, {ERR_FUNC(BIO_F_BIO_NEW_FILE), "BIO_new_file"}, {ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF), "BIO_new_mem_buf"}, {ERR_FUNC(BIO_F_BIO_NREAD), "BIO_nread"}, {ERR_FUNC(BIO_F_BIO_NREAD0), "BIO_nread0"}, {ERR_FUNC(BIO_F_BIO_NWRITE), "BIO_nwrite"}, {ERR_FUNC(BIO_F_BIO_NWRITE0), "BIO_nwrite0"}, {ERR_FUNC(BIO_F_BIO_PARSE_HOSTSERV), "BIO_parse_hostserv"}, {ERR_FUNC(BIO_F_BIO_PUTS), "BIO_puts"}, {ERR_FUNC(BIO_F_BIO_READ), "BIO_read"}, {ERR_FUNC(BIO_F_BIO_SOCKET), "BIO_socket"}, {ERR_FUNC(BIO_F_BIO_SOCKET_NBIO), "BIO_socket_nbio"}, {ERR_FUNC(BIO_F_BIO_SOCK_INFO), "BIO_sock_info"}, {ERR_FUNC(BIO_F_BIO_SOCK_INIT), "BIO_sock_init"}, {ERR_FUNC(BIO_F_BIO_WRITE), "BIO_write"}, {ERR_FUNC(BIO_F_BUFFER_CTRL), "buffer_ctrl"}, {ERR_FUNC(BIO_F_CONN_CTRL), "conn_ctrl"}, {ERR_FUNC(BIO_F_CONN_STATE), "conn_state"}, {ERR_FUNC(BIO_F_DGRAM_SCTP_READ), "dgram_sctp_read"}, {ERR_FUNC(BIO_F_DGRAM_SCTP_WRITE), "dgram_sctp_write"}, {ERR_FUNC(BIO_F_FILE_CTRL), "file_ctrl"}, {ERR_FUNC(BIO_F_FILE_READ), "file_read"}, {ERR_FUNC(BIO_F_LINEBUFFER_CTRL), "linebuffer_ctrl"}, {ERR_FUNC(BIO_F_MEM_WRITE), "mem_write"}, {ERR_FUNC(BIO_F_SSL_NEW), "SSL_new"}, {0, NULL} }; static ERR_STRING_DATA BIO_str_reasons[] = { {ERR_REASON(BIO_R_ACCEPT_ERROR), "accept error"}, {ERR_REASON(BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET),"addrinfo addr is not af inet"}, {ERR_REASON(BIO_R_AMBIGUOUS_HOST_OR_SERVICE),"ambiguous host or service"}, {ERR_REASON(BIO_R_BAD_FOPEN_MODE), "bad fopen mode"}, {ERR_REASON(BIO_R_BROKEN_PIPE), "broken pipe"}, {ERR_REASON(BIO_R_CONNECT_ERROR), "connect error"}, {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),"gethostbyname addr is not af inet"}, {ERR_REASON(BIO_R_GETSOCKNAME_ERROR), "getsockname error"}, {ERR_REASON(BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS),"getsockname truncated address"}, {ERR_REASON(BIO_R_GETTING_SOCKTYPE), "getting socktype"}, {ERR_REASON(BIO_R_INVALID_ARGUMENT), "invalid argument"}, {ERR_REASON(BIO_R_INVALID_SOCKET), "invalid socket"}, {ERR_REASON(BIO_R_IN_USE), "in use"}, {ERR_REASON(BIO_R_LISTEN_V6_ONLY), "listen v6 only"}, {ERR_REASON(BIO_R_LOOKUP_RETURNED_NOTHING), "lookup returned nothing"}, {ERR_REASON(BIO_R_MALFORMED_HOST_OR_SERVICE), "malformed host or service"}, {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR), "nbio connect error"}, {ERR_REASON(BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED),"no accept addr or service specified"}, {ERR_REASON(BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED), "no hostname or service specified"}, {ERR_REASON(BIO_R_NO_PORT_DEFINED), "no port defined"}, {ERR_REASON(BIO_R_NO_SUCH_FILE), "no such file"}, {ERR_REASON(BIO_R_NULL_PARAMETER), "null parameter"}, {ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET), "unable to bind socket"}, {ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET), "unable to create socket"}, {ERR_REASON(BIO_R_UNABLE_TO_KEEPALIVE), "unable to keepalive"}, {ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET), "unable to listen socket"}, {ERR_REASON(BIO_R_UNABLE_TO_NODELAY), "unable to nodelay"}, {ERR_REASON(BIO_R_UNABLE_TO_REUSEADDR), "unable to reuseaddr"}, {ERR_REASON(BIO_R_UNAVAILABLE_IP_FAMILY), "unavailable ip family"}, {ERR_REASON(BIO_R_UNINITIALIZED), "uninitialized"}, {ERR_REASON(BIO_R_UNKNOWN_INFO_TYPE), "unknown info type"}, {ERR_REASON(BIO_R_UNSUPPORTED_IP_FAMILY), "unsupported ip family"}, {ERR_REASON(BIO_R_UNSUPPORTED_METHOD), "unsupported method"}, {ERR_REASON(BIO_R_UNSUPPORTED_PROTOCOL_FAMILY),"unsupported protocol family"}, {ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"}, {ERR_REASON(BIO_R_WSASTARTUP), "WSAStartup"}, {0, NULL} };

  这两个表通过ERR_load_BIO_strings函数来添加到错误信息哈希表中去。为了便于查找,所有模块的错误信息存放在一个全局哈希表中,在crypto/err/err.c实现。

2.2.2 ERR_STATE typedef struct err_state_st { int err_flags[ERR_NUM_ERRORS]; unsigned long err_buffer[ERR_NUM_ERRORS]; //第i层错误码,包含库、函数以及错误原因信息。 char *err_data[ERR_NUM_ERRORS]; //存放第i层操作信息。 int err_data_flags[ERR_NUM_ERRORS]; /*存放err_data[i]相关的标记;比如: 为ERR_TXT_MALLOCED时,表err_data[i]动态分配内存的,需要释放; 为ERR_TXT_STRING表名err_data[i]中的数据是一个字符串,可以用来打印。*/ const char *err_file[ERR_NUM_ERRORS]; //第i层错误的文件名。 int err_line[ERR_NUM_ERRORS]; //第i层错误的行号。 int top, bottom; //用于指明ERR_STATE的使用状态。 //top对应与最后一个错误(错误堆栈的最上层) //bottom对应第一个错误(错误堆栈的最底层)。 } ERR_STATE;

  该结构用于存放和获取错误信息。由于可能会有多层函数调用(错误堆栈),这些信息都是一个数组。每个数组代表了一层函数的错误信息。用户需要扩展openssl的模块时,可以仿照其他已有模块来实现自己的错误处理。

3 相关函数 3.1 获取错误代码

  每当有ERROR产生,一些重要的信息会被记录下来。一些信息可用于尝试自动恢复错误,但是其中的大多数都是用于调试和向用户报告错误。有6个API用于从Error队列中获取信息。ERROR是依产生的顺序记录在队列中的,这些函数都能获取到当前队列中最早的信息。   最基本的消息是一个32-bit integer型的Error code。如果Error队列中无任何消息,error处理函数将返回0,0不是一个有效的错误号。   9个获取error信息的API,实质上都是对get_error_values()的不同参数调用。

//只获取错误代码 unsigned long ERR_get_error(void); //获取第一个,并将其移除队列 unsigned long ERR_peek_error(void); //获取第一个,不移除队列 unsigned long ERR_peek_last_error(void); //获取最后一个,不移除队列 //获取Error code、错误产生的源文件(file)、行号(line) unsigned long ERR_get_error_line(const char **file, int *line); unsigned long ERR_peek_error_line(const char **file, int *line); unsigned long ERR_peek_last_error_line(const char **file, int *line); //获取Error code,错误产生的源文件(file)、行号(line),另提供额外的数据及标识如何处理这些数据的flag unsigned long ERR_get_error_line_data(const char **file, int *line, const char **data, int *flags); unsigned long ERR_peek_error_line_data(const char **file, int *line, const char **data, int *flags); unsigned long ERR_peek_last_error_line_data(const char **file, int *line, const char **data, int *flags); //所获得的数据可能是任意的,但大多数情况下会是一个字符串。 //如flag的ERR_TXT_MALLOCED被置1,则data所使用的内存可以使用OPENSSL_free函数释放。 //如flag的ERR_TXT_STRING被置1,则相应的data可以按C-style字串使用。

  例:打印error队列

void print_errors(void) { int flags, line; char *data, *file; unsigned long code; code = ERR_get_error_line_data(&file, &line, &data, &flags); while(code) { printf("error code: %lu in %s line %d.\n", code, file, line); if(data && (flags & ERR_TXT_STRING)) printf("error data: %s\n", data); code = ERR_get_error_line_data(&file, &line, &data, &flags); } } 3.2 获取错误码对应的错误消息

  error handling package为其定义的error code提供标准的错误消息,但是在使用前需被载入。

// libcrypto和libssl的错误消息全部载入 void SSL_load_error_strings(void) { #ifndef OPENSSL_NO_ERR ERR_load_crypto_strings(); ERR_load_SSL_strings(); #endif: } //libcrypto的错误消息的载入 void ERR_load_crypto_strings(void) { #ifndef OPENSSL_NO_ERR ERR_load_ERR_strings(); /* include error strings for SYSerr */ ERR_load_BN_strings(); #ifndef OPENSSL_NO_RSA ERR_load_RSA_strings(); #endif #ifndef OPENSSL_NO_DH ERR_load_DH_strings(); #endif ERR_load_EVP_strings(); ERR_load_BUF_strings(); ERR_load_OBJ_strings(); ERR_load_PEM_strings(); #ifndef OPENSSL_NO_DSA ERR_load_DSA_strings(); #endif ERR_load_X509_strings(); ERR_load_ASN1_strings(); ERR_load_CONF_strings(); ERR_load_CRYPTO_strings(); ERR_load_COMP_strings(); #ifndef OPENSSL_NO_EC ERR_load_EC_strings(); #endif #ifndef OPENSSL_NO_ECDSA ERR_load_ECDSA_strings(); #endif #ifndef OPENSSL_NO_ECDH ERR_load_ECDH_strings(); #endif /* skip ERR_load_SSL_strings() because it is not in this library */ ERR_load_BIO_strings(); ERR_load_PKCS7_strings(); ERR_load_X509V3_strings(); ERR_load_PKCS12_strings(); ERR_load_RAND_strings(); ERR_load_DSO_strings(); ERR_load_TS_strings(); #ifndef OPENSSL_NO_ENGINE ERR_load_ENGINE_strings(); #endif ERR_load_OCSP_strings(); ERR_load_UI_strings(); #ifndef OPENSSL_NO_CMS ERR_load_CMS_strings(); #endif #ifndef OPENSSL_NO_JPAKE ERR_load_JPAKE_strings(); #endif ERR_load_COMP_strings(); #endif #ifdef OPENSSL_FIPS ERR_load_FIPS_strings(); #endif } // libssl的错误消息的载入 void ERR_load_SSL_strings(void) { #ifndef OPENSSL_NO_ERR if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) { ERR_load_strings(0,SSL_str_functs); ERR_load_strings(0,SSL_str_reasons); } #endif }

  获取错误消息:

//获取全部错误消息 char* ERR_error_string(unsigned long e, char *buf) void ERR_error_string_n(unsigned long e, char *buf, size_t len) //获取错误发生的 库,函数,原因 const char *ERR_lib_error_string(unsigned long e); const char *ERR_func_error_string(unsigned long e); const char *ERR_reason_error_string(unsigned long e); 参数e : error code 参数buf:error message(最少256Byte) 参数len: 写入的消息的最大长度

  error message的格式:

error:error code(hex):error name:产生error的函数名:产生error的原因

  为了获取error信息,必需先获取错误代码ERR_get_error,然后转为错误消息ERR_error_string,OpenSSL提供了下列API来简化这个过程:

//生成一个error list并将其写入BIO void ERR_print_errors(BIO *bp) { ERR_print_errors_cb(print_bio, bp); } //生成一个error list并将其写入一个标准的C FILE对象 void ERR_print_errors_fp(FILE *fp) { ERR_print_errors_cb(print_fp, fp); } 3.3 其它函数 ERR_add_error_data

在本层错误的err_data元素中添加说明信息。该函数一般由各个模块调用,比如可以用它说明什么操作导致了错误。

ERR_clear_error

清除所有的错误信息。如果不清楚所有错误信息,可能会有其他无关错误遗留在ERR_STATE表中。

ERR_free_strings

释放错误信息哈希表;通常在最后调用。

ERR_get_err_state_table

获取存放错误的哈希表。

ERR_get_implementation

获取错误处理函数,与哈希表操作相关。

ERR_get_state

获取ERR_STATE表。

ERR_load_strings

加载错误信息,由各个模块调用。

各个模块实现的,加载各自错误信息。 ERR_load_ASN1_strings ERR_load_BIO_strings ERR_load_BN_strings ERR_load_BUF_strings ERR_load_COMP_strings ERR_load_CONF_strings ERR_load_CRYPTO_strings ERR_load_crypto_strings ERR_load_DH_strings ERR_load_DSA_strings ERR_load_DSO_strings ERR_load_EC_strings ERR_load_ENGINE_strings ERR_load_ERR_strings ERR_load_EVP_strings ERR_load_OBJ_strings ERR_load_OCSP_strings ERR_load_PEM_strings ERR_load_PKCS12_strings ERR_load_PKCS7_strings ERR_load_RAND_strings ERR_load_RSA_strings ERR_load_UI_strings ERR_load_X509_strings ERR_load_X509V3_strings

ERR_print_errors

将错误信息输出到bio中。

ERR_print_errors_cb

根据用户设置的回调函数来打印错误信息。

ERR_print_errors_fp

将错误打印到FILE中。

ERR_put_error

将错误信息存放到ERR_STATE 表中top指定的错误堆栈(最后的错误)。

ERR_remove_state

删除线程相关的错误信息。

ERR_set_error_data

将错误信息存放到ERR_STATE 表中top指定的错误堆栈(最后的错误)。

ERR_unload_strings

从错误哈希表中删除相关信息。

  版权声明:本文根据DragonKing牛,E-Mail:[email protected]发布在https://openssl.126.com的系列文章整理修改而成(这个网站已经不能访问了),我自己所做的工作主要是针对新的1.0.2版本进行验证,修改错别字,和错误,重新排版,以及整理分类,配图。 未经作者允许,严禁用于商业出版,否则追究法律责任。网络转载请注明出处,这是对原创者的起码的尊重!!!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3